package com.example.demo.commons.core.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.example.demo.commons.result.common.enums.BaseErrorCodeEnum;
import com.example.demo.commons.result.common.exception.BizException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;

import static cn.hutool.core.util.IdUtil.getDataCenterId;

/**
 * <p>= 业务单号生成器 </p>
 *
 * @author tanyunpeng
 * @date 2021/11/19
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BizNoUtils {

    private static long WORKER_ID;
    private static long DATACENTER_ID;
    private static Snowflake snowflake;

    static {
        WORKER_ID = getWorkerId();
        //DATACENTER_ID = getDataCenterId();
    }

    /**
     * 获取单例的Twitter的Snowflake 算法生成器对象
     */
    private static Snowflake getSnowflake() {
        if (snowflake != null) {
            return snowflake;
        }
        snowflake = IdUtil.getSnowflake(WORKER_ID, DATACENTER_ID);
        return snowflake;
    }

    /**
     * 32位工作中心节点
     */
    private static Long getWorkerId() {
        String localhostStr = NetUtil.getLocalhostStr();
        if (StringUtils.isBlank(localhostStr)) {
            return RandomUtil.randomLong(0, 32);
        }
        int wkid = localhostStr.hashCode() % 32;
        return (long) (wkid > 0 ? wkid : -wkid);
    }

    /**
     * 32位数据中心节点
     */
//    private static Long getDataCenterId() {
//        long currentPID = SystemUtil.getCurrentPID();
//        return currentPID % 32;
//    }


    /**
     * 获取下一个ID
     */
    private static Long getNextId() {
        Snowflake snowflake = getSnowflake();
        return snowflake.nextId();
    }

    /**
     * 生成单号
     */
    public static String genBillNo(String prefix) {
        if (LocalObjectUtils.anyNull(prefix)) {
            throw BizException.create(BaseErrorCodeEnum.PARAMS_ERROR);
        }
        LocalDate now = LocalDate.now();
        Long nextId = getNextId();
        return StringUtils.join(prefix, Integer.toHexString(now.getYear()), Long.toHexString(nextId));
    }
}
